package com.dayuanit.pay.service.impl;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dayuanit.pay.bank.domain.SinaPayResponse;
import com.dayuanit.pay.bank.factory.PayHandlerFactory;
import com.dayuanit.pay.bank.handler.PayBaseHandler;
import com.dayuanit.pay.bank.handler.SinaPayHandler;
import com.dayuanit.pay.dao.PayOrderDao;
import com.dayuanit.pay.domain.PayOrder;
import com.dayuanit.pay.exception.MallBusException;
import com.dayuanit.pay.mallenum.PayStatus;
import com.dayuanit.pay.service.BankPayService;
import com.dayuanit.pay.service.RedisService;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class BankPayServiceImpl implements BankPayService {
	
	private static final Logger log = LoggerFactory.getLogger(BankPayService.class);
	
	@Autowired
	private PayOrderDao payOrderDao;
	
	@Autowired
	private PayHandlerFactory payHandlerFactory;
	
	@Autowired
	private SinaPayHandler sinaPayHandler;
	
	@Autowired
	private RedisService redisService;

	@Override
	public String pay(int payId, String password) {
		PayOrder po = payOrderDao.getPayOrderById(payId);
		if (null == po) {
			throw new MallBusException("订单无效");
		}
		
		if (PayStatus.ALREADY_PAID.getStatus() == po.getStatus()) {
			throw new MallBusException("订单已支付");
		}
		
		if (PayStatus.PAY_INVALID.getStatus() == po.getStatus()) {
			throw new MallBusException("订单过期");
		}
		
		if (PayStatus.PAY_ING.getStatus() == po.getStatus()) {
			throw new MallBusException("订单正在支付，请稍后");
		}
		
		//TODO 频率限制 和最大错误次数
		if (StringUtils.isBlank(password)) {
			throw new MallBusException("支付密码无效");
		}
		
		//TODO 验证支付密码的准确性
//		if () {
//			
//		}
		
		//TODO 选择支付通道 去支付
		PayBaseHandler hander = payHandlerFactory.getHandler(po.getPayChannel());
		return hander.createOrderPayParam(po);
		
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void processSinaNotify(String data) {
		
		//TODO 验签
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			SinaPayResponse sr = objectMapper.readValue(data, SinaPayResponse.class);
			String sign = sr.getSignMsg();
			boolean signFlag = sinaPayHandler.checkNotifySigin(sign, sr);
			if (!signFlag) {
				throw new MallBusException("非法签名");
			}
			
			int payId = Integer.valueOf(sr.getOrderId());
			PayOrder payOrder = payOrderDao.getPayOrderById(payId);
			if (PayStatus.ALREADY_PAID.getStatus() == payOrder.getStatus()) {
				return;
			}
			
			int rows = payOrderDao.updatePayStatus(payOrder.getId(), PayStatus.PAY_ING.getStatus(), payOrder.getStatus());
			if (rows != 1) {
				log.error("用户{}支付订单{}更新失败，状态{}改为{}", payOrder.getUserId(), String.valueOf(payOrder.getId()), String.valueOf(payOrder.getStatus()), String.valueOf(PayStatus.PAY_ING.getStatus()));
				throw new MallBusException("订单支付失败");
			}
			
			rows = payOrderDao.updatePayStatus(payId, PayStatus.ALREADY_PAID.getStatus(), PayStatus.PAY_ING.getStatus());
			if (1 != rows) {
				throw new MallBusException("支付订单处理失败" + sr.getOrderId());
			}
			log.info("订单{}支付成功", sr.getOrderId());
			
			//将支付成功的订单加入到队列里 数据格式 bizId$payId
			String orderNotifyValue = payOrder.getBizId() + "$" + payOrder.getId();
			redisService.addPayedOrder(orderNotifyValue);
		} catch (Exception e) {
			log.error("处理新浪异步通知消息异常{}", e.getMessage(), e);
			throw new MallBusException("处理新浪异步通知消息异常");
		}
				
	}

}
